home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / Report Writers / Crystal Repot 9.0 Full CD version / Setup.exe / ProgramF / CRYSTAL / CRW9 / DEV / INCLUDE / UFLSAMP1.C < prev    next >
Encoding:
C/C++ Source or Header  |  2002-01-18  |  8.6 KB  |  363 lines

  1. /*
  2. ** File:    UFLSamp1.c
  3. ** Author:  Rick Cameron
  4. ** Date:    8 Mar 93
  5. **
  6. ** Purpose: Example user-defined functions.
  7. */
  8.  
  9. #if defined( _WIN32 ) && defined( _MSC_VER ) && _MSC_VER >= 1000
  10. #define _export __declspec(dllexport)
  11. #endif
  12.  
  13. #include <windows.h>
  14. #include "ufdll.h"
  15. #include "ufmain.h"
  16. #include "ufuser.h"
  17. #include "ufjob.h"
  18.  
  19. #include <ctype.h>
  20.  
  21. #define PicturePlaceholder 'x'
  22.  
  23. #define WildOneChar  '?'
  24. #define WildAllChars '*'
  25.  
  26. #define SoundexLength 4
  27.  
  28. #define MAX_TIME_STRING_LEN     2 + 1 + 2 + 1 + 2 + 1 + 4 + 1
  29.  
  30.  
  31. UFError FAR CR_EXPORT Now (UFParamBlock * ParamBlock);
  32. UFError FAR CR_EXPORT Picture (UFParamBlock * ParamBlock);
  33. UFError FAR CR_EXPORT LooksLike (UFParamBlock * ParamBlock);
  34. UFError FAR CR_EXPORT Soundex (UFParamBlock * ParamBlock);
  35.  
  36. UFError FAR CR_EXPORT NowStringRetSize (UFMemCalcBlock * ParamBlock);
  37. UFError FAR CR_EXPORT SoundexStringRetSize (UFMemCalcBlock * ParamBlock);
  38.  
  39. UF5FunctionDefStrings FunctionDefStrings [] =
  40. {
  41.     {"String Now", Now, NowStringRetSize, FALSE, FALSE},
  42.  
  43.     {"String Picture (String, String)", Picture, NULL, FALSE, FALSE},
  44.  
  45.     {"Boolean LooksLike (String, String)", LooksLike, NULL, FALSE, FALSE},
  46.  
  47.     {"String Soundex (String)", Soundex, SoundexStringRetSize, FALSE, FALSE},
  48.  
  49.     {NULL, NULL, NULL, FALSE, FALSE}
  50. };
  51.  
  52. UFFunctionTemplates FunctionTemplates [] =
  53. {
  54.     {"Now!"},
  55.  
  56.     {"Picture (!, )"},
  57.  
  58.     {"LooksLike (!, )"},
  59.  
  60.     {"Soundex (!)"},
  61.  
  62.     {NULL}
  63. };
  64.  
  65. UFFunctionExamples FunctionExamples [] =
  66. {
  67.     {"\tNow"},
  68.  
  69.     {"\tPicture (string, picture)"},
  70.  
  71.     {"\tLooksLike (string, mask)"},
  72.  
  73.     {"\tSoundex (string)"},
  74.  
  75.     {NULL}
  76. };
  77.  
  78. char *ErrorTable [] =
  79. {
  80.     "no error",
  81. };
  82.  
  83. void InitJob (struct JobInfo *jobInfo)
  84. {
  85. }
  86.  
  87. void TermJob (struct JobInfo *jobInfo)
  88. {
  89. }
  90.  
  91. UFError FAR CR_EXPORT Now (UFParamBlock * ParamBlock)
  92. {
  93.     // Get the current time and display it using the current locale settings.
  94.     SYSTEMTIME systime;
  95.     GetLocalTime (&systime);
  96.  
  97.     GetTimeFormat (LOCALE_USER_DEFAULT,
  98.                                 0,
  99.                                 &systime,
  100.                                 NULL,
  101.                                 ParamBlock->ReturnValue.ReturnString,
  102.                                 MAX_TIME_STRING_LEN);
  103.  
  104.     return UFNoError;
  105. }
  106.  
  107. UFError FAR CR_EXPORT NowStringRetSize (UFMemCalcBlock * ParamBlock)
  108. {
  109.     // The longest string possible is "01:01:01 abcd"
  110.     ParamBlock->UFMemCalcStringLength = MAX_TIME_STRING_LEN;
  111.     return UFNoError;
  112. }
  113.  
  114. static void copyUsingPicture (char *dest,
  115.                               const char *source,
  116.                               const char *picture)
  117. {
  118.     while (*picture != '\0')
  119.     {
  120.         if (tolower (*picture) == PicturePlaceholder)
  121.             if (*source != '\0')
  122.                 *dest++ = *source++;
  123.             else
  124.                 ; // don't insert anything
  125.         else
  126.             *dest++ = *picture;
  127.  
  128.         picture++;
  129.     }
  130.  
  131.     // copy the rest of the source
  132.     lstrcpy (dest, source);
  133. }
  134.  
  135. UFError FAR CR_EXPORT Picture (UFParamBlock * ParamBlock)
  136. {
  137.     UFParamListElement *FirstParam,
  138.                        *SecondParam;
  139.     char *buffer;
  140.     UFTInt32u outLength;
  141.  
  142.     FirstParam  = GetParam (ParamBlock, 1);
  143.     SecondParam = GetParam (ParamBlock, 2);
  144.  
  145.     if (FirstParam == NULL || SecondParam == NULL)
  146.         return UFNotEnoughParameters;
  147.  
  148.     // max length of return string is the sum of parameter string lengthes
  149.     outLength = lstrlen (FirstParam->Parameter.ParamString) + lstrlen (FirstParam->Parameter.ParamString);
  150.     if (outLength <= UFMaxStringLength)
  151.         buffer = ParamBlock->ReturnValue.ReturnString;
  152.     else
  153.     {
  154.         buffer = (char *) malloc (outLength + 1);
  155.         if (buffer == 0)
  156.             return UFNoMemory;
  157.     }
  158.  
  159.     copyUsingPicture (buffer,
  160.                       FirstParam->Parameter.ParamString,
  161.                       SecondParam->Parameter.ParamString);
  162.  
  163.     if (outLength > UFMaxStringLength)
  164.     {
  165.         // trucate the output result to avoid overwriting memory
  166.         // ParamBlock->ReturnValue.ReturnString is 255 bytes
  167.         // UFMaxStringLength is 254
  168.         lstrcpyn (ParamBlock->ReturnValue.ReturnString, buffer, UFMaxStringLength + 1);
  169.         free (buffer);
  170.     }
  171.     return UFNoError;
  172. }
  173.  
  174. static UFTBoolean looksLike (const char *string, const char *mask)
  175. {
  176.     while (*mask != '\0')
  177.     {
  178.         if (*mask == WildAllChars)
  179.             return TRUE;
  180.         else if (*mask == WildOneChar)
  181.         {
  182.             if (*string == '\0')
  183.                 return FALSE;
  184.         }
  185.         else if (*mask != *string)
  186.             return FALSE;
  187.  
  188.         ++mask;
  189.         ++string;
  190.     }
  191.  
  192.     return (*string == '\0');
  193. }
  194.  
  195. UFError FAR CR_EXPORT LooksLike (UFParamBlock * ParamBlock)
  196. {
  197.     UFParamListElement *FirstParam,
  198.                        *SecondParam;
  199.  
  200.     FirstParam  = GetParam (ParamBlock, 1);
  201.     SecondParam = GetParam (ParamBlock, 2);
  202.  
  203.     if (FirstParam == NULL || SecondParam == NULL)
  204.         return UFNotEnoughParameters;
  205.  
  206.     ParamBlock->ReturnValue.ReturnBoolean
  207.         = looksLike (FirstParam->Parameter.ParamString,
  208.                      SecondParam->Parameter.ParamString);
  209.  
  210.     return UFNoError;
  211. }
  212.  
  213. // static Int16u soundexCode
  214.  
  215. typedef enum
  216. {
  217.     nonAlpha = -1,
  218.     ignored  = '0',
  219.     bfpv     = '1',
  220.     cgjkqsxz = '2',
  221.     dt       = '3',
  222.     l        = '4',
  223.     mn       = '5',
  224.     r        = '6'
  225. } SoundexCode;
  226.  
  227. static char AnsiLowerChar (char c)
  228. {
  229. #ifdef _WIN32
  230.     // for charactors that are a negative sign number e.g. 'Θ' 
  231.     // because CharUpper and CharLower is expecting the hiword of LPTSTR 
  232.     // to be 0 if the given parameter is a single char, otherwise the 
  233.     // it will GPF.
  234.     LPTSTR pc = (LPTSTR) (BYTE) c;
  235.     return LOBYTE (LOWORD (CharLower (pc)));
  236. #else
  237.     return LOBYTE (LOWORD (AnsiLower (MAKELP (0, c))));
  238. #endif
  239. }
  240.  
  241. static char AnsiUpperChar (char c)
  242. {
  243. #ifdef _WIN32
  244.     // for charactors that are a negative sign number e.g. 'Θ' 
  245.     // because CharUpper and CharLower is expecting the hiword of LPTSTR 
  246.     // to be 0 if the given parameter is a single char, otherwise the 
  247.     // it will GPF.
  248.     LPTSTR pc = (LPTSTR) (BYTE) c;  
  249.     return LOBYTE (LOWORD (CharUpper (pc)));
  250. #else
  251.     return LOBYTE (LOWORD (AnsiUpper (MAKELP (0, c))));
  252. #endif
  253. }
  254.  
  255. static SoundexCode calcCode (char c)
  256. {
  257.     if (!IsCharAlpha (c))
  258.         return nonAlpha;
  259.  
  260.     c = AnsiLowerChar (c);
  261.  
  262.     switch (c)
  263.     {
  264.         case 'b': case 'f': case 'p': case 'v':
  265.              return bfpv;
  266.  
  267.         case 'c': case 'g': case 'j': case 'k':
  268.         case 'q': case 's': case 'x': case 'z':
  269.         case '▀': case 'τ': case 'Ü': // s with an inverted ^
  270.              return cgjkqsxz;
  271.  
  272.         case 'd': case 't':
  273.         case '≡': case '■':
  274.              return dt;
  275.  
  276.         case 'l':
  277.              return l;
  278.  
  279.         case 'm': case 'n':
  280.         case '±':
  281.              return mn;
  282.  
  283.         case 'r':
  284.              return r;
  285.  
  286.         default:
  287.              return ignored;
  288.     }
  289. }
  290.  
  291. static const char *skipBlanks (const char *string)
  292. {
  293.     while (*string == ' ')
  294.         ++string;
  295.  
  296.     return string;
  297. }
  298.  
  299. static void calcSoundex (char *buffer, const char *string)
  300. {
  301.     const char *inCursor  = string,
  302.                *bufferEnd = buffer + SoundexLength;
  303.     char       *outCursor = buffer;
  304.     SoundexCode code;
  305.  
  306.     inCursor = skipBlanks (inCursor);
  307.  
  308.     code = calcCode (*inCursor);
  309.  
  310.     if (code == nonAlpha)
  311.         *outCursor++ = '0';
  312.     else
  313.         *outCursor++ = AnsiUpperChar (*inCursor++);
  314.  
  315.     while (code != nonAlpha
  316.            && *inCursor != '\0'
  317.            && outCursor < bufferEnd)
  318.     {
  319.         SoundexCode lastCode = code;
  320.  
  321.         code = calcCode (*inCursor);
  322.  
  323.         if (code == nonAlpha)
  324.             ;
  325.         else
  326.         {
  327.             if (code == lastCode)
  328.                 ;
  329.             else if (code == ignored)
  330.                 code = lastCode;
  331.             else
  332.                 *outCursor++ = code;
  333.  
  334.             ++inCursor;
  335.         }
  336.     }
  337.  
  338.     while (outCursor < bufferEnd)
  339.            *outCursor++ = '0';
  340.  
  341.     *outCursor = '\0';
  342. }
  343.  
  344. UFError FAR CR_EXPORT Soundex (UFParamBlock * ParamBlock)
  345. {
  346.     UFParamListElement * ParamPtr;
  347.  
  348.     ParamPtr = GetParam (ParamBlock, 1);
  349.     if (ParamPtr == NULL)
  350.         return UFNotEnoughParameters;
  351.  
  352.     calcSoundex (ParamBlock->ReturnValue.ReturnString,
  353.                  ParamPtr->Parameter.ParamString);
  354.  
  355.     return UFNoError;
  356. }
  357.  
  358. UFError FAR CR_EXPORT SoundexStringRetSize (UFMemCalcBlock *ParamBlock)
  359. {
  360.     ParamBlock->UFMemCalcStringLength = SoundexLength + 1;
  361.     return UFNoError;
  362. }
  363.